// tuple standard header
#ifndef _TUPLE_
#define _TUPLE_
#include <type_traits>
#include <xutility>
#include <new>

_STD_BEGIN
	// STRUCT _Tuple_enable
template<class _Src,
	class _Dest>
	struct _Tuple_enable
	{	// default has no type definition
	};

template<>
	struct _Tuple_enable<tuple<>, tuple<> >
	{	// empty tuples match
	typedef void ** type;
	};

 #if _HAS_VARIADIC_TEMPLATES
template<class _Src0,
	class... _Types1,
	class _Dest0,
	class... _Types2>

 #if _CLANG	/* compiler test */
	struct _Tuple_enable<tuple<_Src0, _Types1...>,
		tuple<_Dest0, _Types2...> >
	: _If<is_convertible<
			typename remove_reference<_Src0>::type,
			typename remove_reference<_Dest0>::type>::value,
		_Tuple_enable<tuple<_Types1...>, tuple<_Types2...> >,
		_Tuple_enable<int, int>
	>::type
	{	// tests if all tuple element pairs are implicitly convertible
	};

 #else /* _CLANG */
	struct _Tuple_enable<tuple<_Src0, _Types1...>,
		tuple<_Dest0, _Types2...> >
	: _If<is_convertible<_Src0, _Dest0>::value,
		_Tuple_enable<tuple<_Types1...>, tuple<_Types2...> >,
		_Tuple_enable<int, int>
	>::type
	{	// tests if all tuple element pairs are implicitly convertible
	};
 #endif /* _CLANG */

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _TUPLE_ENABLE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _Src0, \
	class _Dest0 _EX(C) LIST(_CLASS_TYPE) _EX(C) LIST(_CLASS_TYPEX)> \
	struct _Tuple_enable< \
		tuple<_Src0 _EX(C) LIST(_TYPE)>, \
		tuple<_Dest0 _EX(C) LIST(_TYPEX)> > \
	: _If<is_convertible< \
			typename remove_reference<_Src0>::type, \
			typename remove_reference<_Dest0>::type>::value, \
		_Tuple_enable<tuple<LIST(_TYPE)>, tuple<LIST(_TYPEX)> >, \
		_Tuple_enable<int, int> \
	>::type \
	{	/* test if all tuple element pairs are implicitly convertible */ \
	};

_VARIADIC_EXPAND_0X(_TUPLE_ENABLE, , , , )
#undef _TUPLE_ENABLE
 #endif /* _HAS_VARIADIC_TEMPLATES */

	// STRUCT _Ignore
struct _Ignore
	{	// struct that ignores assignments
	template<class _Ty>
		void operator=(const _Ty&) const
		{	// do nothing
		}
	};

 #if _HAS_CPP1X
_CONST_DATA _Ignore ignore{};
 #else /* _HAS_CPP1X */
_CONST_DATA _Ignore ignore = _Ignore();
 #endif /* _HAS_CPP1X */

		// STRUCT _Tuple_alloc_t
struct _Tuple_alloc_t
	{	// tag type to disambiguate added allocator argument
	};

 #if _HAS_CPP1X
_CONST_DATA _Tuple_alloc_t _Tuple_alloc{};
 #else /* _HAS_CPP1X */
_CONST_DATA _Tuple_alloc_t _Tuple_alloc = _Tuple_alloc_t();
 #endif /* _HAS_CPP1X */

	// TEMPLATE CLASS _Tuple_val
template<class _Ty>
	struct _Tuple_val
	{	// stores each value in a tuple
	_CONST_FUN _Tuple_val()
		: _Val()
		{	// default construct
		}

 #if _HAS_RVALUE_REFERENCES
	template<class _Other>
		_CONST_FUN _Tuple_val(_Other&& _Arg)
		: _Val(_STD forward<_Other>(_Arg))
		{	// construct with argument
		}

	template<class _Other>
		_Tuple_val& operator=(_Other&& _Right)
		{	// assign
		_Val = _STD forward<_Other>(_Right);
		return (*this);
		}

 #else /* _HAS_RVALUE_REFERENCES */

	template<class _Other>
		_Tuple_val(const _Other& _Arg)
		: _Val(_Arg)
		{	/* construct with const argument */
		}

	template<class _Other>
		_Tuple_val(_Other& _Arg)
		: _Val(_Arg)
		{	/* construct with non-const argument */
		}
 #endif /* _HAS_RVALUE_REFERENCES */

 #if _HAS_VARIADIC_TEMPLATES
	template<class _Alloc,
		class... _Other>
		_Tuple_val(const _Alloc&,
			typename enable_if<!uses_allocator<_Ty, _Alloc>::value,
				_Tuple_alloc_t>::type, _Other&&... _Arg)
		: _Val(_STD forward<_Other>(_Arg)...)
		{	// construct with optional arguments, no allocator
		}

	template<class _Alloc,
		class... _Other>
		_Tuple_val(const _Alloc& _Al,
			typename enable_if<uses_allocator<_Ty, _Alloc>::value
				&& is_constructible<_Ty,
					allocator_arg_t, _Alloc>::value,
				_Tuple_alloc_t>::type, _Other&&... _Arg)
		: _Val(allocator_arg, _Al, _STD forward<_Other>(_Arg)...)
		{	// construct with optional arguments, leading allocator
		}

	template<class _Alloc,
		class... _Other>
		_Tuple_val(const _Alloc& _Al,
			typename enable_if<uses_allocator<_Ty, _Alloc>::value
				&& !is_constructible<_Ty,
					allocator_arg_t, _Alloc>::value,
				_Tuple_alloc_t>::type, _Other&&... _Arg)
		: _Val(_STD forward<_Other>(_Arg)..., _Al)
		{	// construct with optional arguments, trailing allocator
		}

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _TUPLE_VAL_CONSTRUCTOR( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<class _Alloc _EX(C) LIST(_CLASS_TYPE)> \
		_Tuple_val(const _Alloc&, \
			typename enable_if<!uses_allocator<_Ty, _Alloc>::value, \
				_Tuple_alloc_t>::type _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Val(LIST(_FORWARD_ARG)) \
		{	/* construct with optional arguments, no allocator */ \
		} \
	template<class _Alloc _EX(C) LIST(_CLASS_TYPE)> \
		_Tuple_val(const _Alloc& _Al, \
			typename enable_if<uses_allocator<_Ty, _Alloc>::value \
				&& is_constructible<_Ty, \
					allocator_arg_t, _Alloc>::value, \
				_Tuple_alloc_t>::type _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Val(allocator_arg, _Al _EX(C) LIST(_FORWARD_ARG)) \
		{	/* construct with optional arguments, leading allocator */ \
		} \
	template<class _Alloc _EX(C) LIST(_CLASS_TYPE)> \
		_Tuple_val(const _Alloc& _Al, \
			typename enable_if<uses_allocator<_Ty, _Alloc>::value \
				&& !is_constructible<_Ty, \
					allocator_arg_t, _Alloc>::value, \
				_Tuple_alloc_t>::type _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Val(LIST(_FORWARD_ARG) _EX(C) _Al) \
		{	/* construct with arguments, trailing allocator */ \
		}

_VARIADIC_EXPAND_0X(_TUPLE_VAL_CONSTRUCTOR, , , , )
#undef _TUPLE_VAL_CONSTRUCTOR
 #endif /* _HAS_VARIADIC_TEMPLATES */

	_Ty _Val;
	};

 #if _HAS_VARIADIC_TEMPLATES
	// CLASS tuple
template<class... _Types>
	class tuple;

template<>
	class tuple<>
	{	// empty tuple
public:
	typedef tuple<> _Myt;
	typedef _Myt _This_type;

	_CONST_FUN tuple() _NOEXCEPT
		{	// default construct
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT
		{	// default construct, allocator
		}

	_CONST_FUN tuple(const tuple&) _NOEXCEPT
		{	// copy construct
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc&, const _Myt&) _NOEXCEPT
		{	// copy construct, allocator
		}

	void swap(_Myt&) _NOEXCEPT
		{	// swap elements
		}

	_CONST_FUN bool _Equals(const _Myt&) const _NOEXCEPT
		{	// test if *this == _Right
		return (true);
		}

	_CONST_FUN bool _Less(const _Myt&) const _NOEXCEPT
		{	// test if *this < _Right
		return (false);
		}
	};

struct _One_arg_t
	{	// tag type to disambiguate construction
	};

template<class _This,
	class... _Rest>
	class tuple<_This, _Rest...>

 #if 0 < __GNUC__	/* compiler test */
		: public tuple<_Rest...>
 #elif defined(__CODEGEARC__) && defined(__clang__)  // FIXME
		: public tuple<_Rest...>
 #else /* 0 < __GNUC__ */
		: private tuple<_Rest...>
 #endif /* 0 < __GNUC__ */

	{	// recursive tuple definition
public:
	typedef _This _This_type;
	typedef tuple<_This, _Rest...> _Myt;
	typedef tuple<_Rest...> _Mybase;
	static const size_t _Mysize = 1 + sizeof...(_Rest);

	_CONST_FUN tuple()
		: _Mybase(),
			_Myfirst()
		{	// construct default
		}

	template<class... _Rest2>
		explicit tuple(_Tuple_alloc_t, _Rest2&&... _Rest_arg)
			: _Mybase(_STD forward<_Rest2>(_Rest_arg)...),
				_Myfirst(allocator_arg)
		{	// construct smuggled allocator_arg_t element
		}

	template<class... _Other,
		class = typename _Tuple_enable<
			tuple<const _Other&...>, _Myt>::type>
		_CONST_FUN tuple(const tuple<_Other...>& _Right)
		: _Mybase(_Right._Get_rest()), _Myfirst(_Right._Myfirst._Val)
		{	// construct by copying same size tuple
		}

	template<class _Alloc,
		class... _Other,
		class = typename _Tuple_enable<
			tuple<const _Other&...>, _Myt>::type>
		tuple(allocator_arg_t, const _Alloc& _Al,
			const tuple<_Other...>& _Right)
		: _Mybase(allocator_arg, _Al, _Right._Get_rest()),
			_Myfirst(_Al, _Tuple_alloc,
				_Right._Myfirst._Val)
		{	// construct by copying same size tuple, allocator
		}

	_CONST_FUN explicit tuple(const _This& _This_arg,
		const _Rest&... _Rest_arg)
		: _Mybase(_Rest_arg...),
			_Myfirst(_This_arg)
		{	// construct from one or more copied elements
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc& _Al,
			const _This& _This_arg, const _Rest&... _Rest_arg)
		: _Mybase(allocator_arg, _Al, _Rest_arg...),
			_Myfirst(_Al, _Tuple_alloc, _This_arg)
		{	// construct from one or more copied elements, allocator
		}

	template<class _This2,
		class... _Rest2,
		class = typename _Tuple_enable<
			tuple<_This2, _Rest2...>, _Myt>::type>
		_CONST_FUN explicit tuple(_This2&& _This_arg, _Rest2&&... _Rest_arg)
		: _Mybase(_STD forward<_Rest2>(_Rest_arg)...),
			_Myfirst(_STD forward<_This2>(_This_arg))
		{	// construct from one or more moved elements
		}

	template<class _Alloc,
		class _This2,
		class... _Rest2,
		class = typename _Tuple_enable<
			tuple<_This2, _Rest2...>, _Myt>::type>
		tuple(allocator_arg_t, const _Alloc& _Al,
			_This2&& _This_arg, _Rest2&&... _Rest_arg)
		: _Mybase(allocator_arg, _Al,
				_STD forward<_Rest2>(_Rest_arg)...),
			_Myfirst(_Al, _Tuple_alloc,
				_STD forward<_This2>(_This_arg))
		{	// construct from one or more moved elements, allocator
		}

	template<class... _Other,
		class = typename _Tuple_enable<
			tuple<_Other...>, _Myt>::type>
		_CONST_FUN tuple(tuple<_Other...>&& _Right)
		: _Mybase((typename tuple<_Other...>::_Mybase&&)_Right),
			_Myfirst(_STD forward<typename tuple<_Other...>::_This_type>
				(_Right._Myfirst._Val))
		{	// construct by moving same size tuple
		}

	template<class _Alloc,
		class... _Other,
		class = typename _Tuple_enable<
			tuple<_Other...>, _Myt>::type>
		tuple(allocator_arg_t, const _Alloc& _Al,
			tuple<_Other...>&& _Right)
		: _Mybase(allocator_arg, _Al,
				_STD forward<typename tuple<_Other...>::_Mybase>
					(_Right._Get_rest())),
			_Myfirst(_Al, _Tuple_alloc,
				_STD forward<typename tuple<_Other...>::_This_type>
					(_Right._Myfirst._Val))
		{	// construct by moving same size tuple, allocator
		}

	template<class... _Other>
		_Myt& operator=(const tuple<_Other...>& _Right)
		{	// assign by copying same size tuple
		_Myfirst._Val = _Right._Myfirst._Val;
		_Get_rest() = _Right._Get_rest();
		return (*this);
		}

	template<class... _Other>
		_Myt& operator=(tuple<_Other...>&& _Right)
		{	// assign by moving same size tuple
		_Myfirst._Val = _STD forward<typename tuple<_Other...>::_This_type>
			(_Right._Myfirst._Val);
		_Get_rest() = _STD forward<typename tuple<_Other...>::_Mybase>
			(_Right._Get_rest());
		return (*this);
		}

	template<class... _Other>
		_CONST_FUN bool _Equals(const tuple<_Other...>& _Right) const
		{	// test if *this == _Right
		_STATIC_ASSERT2(_Mysize == sizeof...(_Other),
			"comparing tuple to object with different size");
		return (_Myfirst._Val == _Right._Myfirst._Val
			&& _Mybase::_Equals(_Right._Get_rest()));
		}

	template<class... _Other>
		_CONST_FUN bool _Less(const tuple<_Other...>& _Right) const
		{	// test if *this < _Right
		_STATIC_ASSERT2(_Mysize == sizeof...(_Other),
			"comparing tuple to object with different size");
		return (_Myfirst._Val < _Right._Myfirst._Val
			|| (!(_Right._Myfirst._Val < _Myfirst._Val)
				&& _Mybase::_Less(_Right._Get_rest())));
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc& _Al)
		: _Mybase(allocator_arg, _Al),
			_Myfirst(_Al, _Tuple_alloc)
		{	// construct default, allocator
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc& _Al,
			const _Myt& _Right)
		: _Mybase(allocator_arg, _Al, _Right._Get_rest()),
			_Myfirst(_Al, _Tuple_alloc,
				_Right._Myfirst._Val)
		{	// construct by copying, allocator
		}

 #if 0 < _MSC_VER
	tuple(const _Myt&) = default;

	tuple(_Myt&& _Right)
		: _Mybase(_STD forward<_Mybase>(_Right._Get_rest())),
			_Myfirst(_STD forward<_This>(_Right._Myfirst._Val))
		{	// construct by moving
		}

 #else /* 0 < _MSC_VER */
	tuple(const _Myt&) = default;
	tuple(_Myt&&) = default;
 #endif /* 0 < _MSC_VER */

	template<class _Tag,
		class _This2,
		class = typename enable_if<is_same<_Tag, _One_arg_t>::value>::type>
		_CONST_FUN tuple(_Tag, _This2&& _This_arg)
		: _Mybase(),
			_Myfirst(_STD forward<_This2>(_This_arg))
		{	// construct from one perfectly forwarded element
		}

 #if _HAS_NEW_SFINAE
	template<class _First,
		class _Second,
		class = typename _Tuple_enable<
			tuple<const _First&, const _Second&>, _Myt>::type>
		_CONST_FUN tuple(const pair<_First, _Second>& _Right)

 #else /* _HAS_NEW_SFINAE */
	template<class _First,
		class _Second>
		_CONST_FUN tuple(const pair<_First, _Second>& _Right,
			typename _Tuple_enable<
				tuple<const _First&, const _Second&>, _Myt>::type = 0)
 #endif /* _HAS_NEW_SFINAE */

		: _Mybase(_One_arg_t(), _Right.second),
			_Myfirst(_Right.first)
		{	// construct by copying pair
		// no static_assert necessary
		}

 #if _HAS_NEW_SFINAE
	template<class _Alloc,
		class _First,
		class _Second,
		class = typename _Tuple_enable<
			tuple<const _First&, const _Second&>, _Myt>::type>
		tuple(allocator_arg_t, const _Alloc& _Al,
			const pair<_First, _Second>& _Right)

 #else /* _HAS_NEW_SFINAE */
	template<class _Alloc,
		class _First,
		class _Second>
		tuple(allocator_arg_t, const _Alloc& _Al,
			const pair<_First, _Second>& _Right,
			typename _Tuple_enable<
				tuple<const _First&, const _Second&>, _Myt>::type = 0)
 #endif /* _HAS_NEW_SFINAE */

		: _Mybase(allocator_arg, _Al, tuple<_Second>(_Right.second)),
			_Myfirst(_Al, _Tuple_alloc,
				_Right.first)
		{	// construct by copying pair, allocator
		// no static_assert necessary
		}

	_Myt& operator=(const _Myt& _Right)
		{	// assign
		_Myfirst._Val = _Right._Myfirst._Val;
		_Get_rest() = _Right._Get_rest();
		return (*this);
		}

	template<class _First,
		class _Second>
		_Myt& operator=(const pair<_First, _Second>& _Right)
		{	// assign by copying pair
		_STATIC_ASSERT2(_Mysize == 2,
			"assigning to tuple from object with different size");
		_Myfirst._Val = _Right.first;
		_Get_rest()._Myfirst._Val = _Right.second;
		return (*this);
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc& _Al,
			_Myt&& _Right)
		: _Mybase(allocator_arg, _Al,
				_STD forward<_Mybase>(_Right._Get_rest())),
			_Myfirst(_Al, _Tuple_alloc,
				_STD forward<_This>(_Right._Myfirst._Val))
		{	// construct by moving, allocator
		}

 #if _HAS_NEW_SFINAE
	template<class _First,
		class _Second,
		class = typename _Tuple_enable<
			tuple<_First, _Second>, _Myt>::type>
		_CONST_FUN tuple(pair<_First, _Second>&& _Right)

 #else /* _HAS_NEW_SFINAE */
	template<class _First,
		class _Second>
		_CONST_FUN tuple(pair<_First, _Second>&& _Right,
			typename _Tuple_enable<
				tuple<const _First&, const _Second&>, _Myt>::type = 0)
 #endif /* _HAS_NEW_SFINAE */

		: _Mybase(_One_arg_t(), _STD forward<_Second>(_Right.second)),
			_Myfirst(_STD forward<_First>(_Right.first))
		{	// construct by moving pair
		// no static_assert necessary
		}

 #if _HAS_NEW_SFINAE
	template<class _Alloc,
		class _First,
		class _Second,
		class = typename _Tuple_enable<
			tuple<_First, _Second>, _Myt>::type>
		tuple(allocator_arg_t, const _Alloc& _Al,
			pair<_First, _Second>&& _Right)

 #else /* _HAS_NEW_SFINAE */
	template<class _Alloc,
		class _First,
		class _Second>
		tuple(allocator_arg_t, const _Alloc& _Al,
			pair<_First, _Second>&& _Right,
			typename _Tuple_enable<
				tuple<const _First&, const _Second&>, _Myt>::type = 0)
 #endif /* _HAS_NEW_SFINAE */

		: _Mybase(allocator_arg, _Al,
				tuple<_Second>(_STD forward<_Second>(_Right.second))),
			_Myfirst(_Al, _Tuple_alloc,
				_STD forward<_First>(_Right.first))
		{	// construct by moving pair, allocator
		// no static_assert necessary
		}

	_Myt& operator=(_Myt&& _Right)
		_NOEXCEPT_OP(is_nothrow_move_assignable<_This>::value
			&& is_nothrow_move_assignable<_Mybase>::value)
		{	// assign by moving
		_Myfirst._Val = _STD forward<_This>(_Right._Myfirst._Val);
		_Get_rest() = _STD forward<_Mybase>(_Right._Get_rest());
		return (*this);
		}

	template<class _First,
		class _Second>
		_Myt& operator=(pair<_First, _Second>&& _Right)
		{	// assign by moving pair
		_STATIC_ASSERT2(_Mysize == 2,
			"assigning to tuple from object with different size");
		_Myfirst._Val = _STD forward<_First>(_Right.first);
		_Get_rest()._Myfirst._Val = _STD forward<_Second>(_Right.second);
		return (*this);
		}

	_Mybase& _Get_rest() _NOEXCEPT
		{	// get reference to rest of elements
		return (*this);
		}

	_CONST_FUN const _Mybase& _Get_rest() const _NOEXCEPT
		{	// get const reference to rest of elements
		return (*this);
		}

	void swap(tuple& _Right)
		_NOEXCEPT_OP(
			_NOEXCEPT_OP(_Swap_adl(this->_Myfirst._Val, _Right._Myfirst._Val))
			&& _NOEXCEPT_OP(_Swap_adl(_Right._Get_rest(), _Right._Get_rest())))
		{	// swap *this and _Right
		_Swap_adl(_Myfirst._Val, _Right._Myfirst._Val);
		_Mybase::swap(_Right._Get_rest());
		}

	_Tuple_val<_This> _Myfirst;	// the stored element
	};

 #else /* _HAS_VARIADIC_TEMPLATES */
	// CLASS tuple
//template<class = _Nil, _MAX_CLASS_LIST>
//	class tuple;

template<>
	class tuple<_Nil, _MAX_NIL_LIST>
	{	// empty tuple
public:
	typedef tuple<> _Myt;

	tuple()
		{	// default construct
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT
		{	// default construct, allocator
		}

	tuple(const tuple&) _NOEXCEPT
		{	// copy construct
		}

	template<class _Alloc>
		tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT
		{	// copy construct, allocator
		}

	void swap(_Myt&) _NOEXCEPT
		{	// swap elements
		}

	bool _Equals(const _Myt&) const _NOEXCEPT
		{	// test if *this == _Right
		return (true);
		}

	bool _Less(const _Myt&) const _NOEXCEPT
		{	// test if *this < _Right
		return (false);
		}
	};

#define _CLASS_TUPLE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _This _EX(C) LIST(_CLASS_TYPEX)> \
	class tuple<_This _EX(C) LIST(_TYPEX), PADDING_LIST(_NIL_PAD)> \
	: private tuple<LIST(_TYPEX) _EX(C) PADDING_LIST(_NIL_PAD)> \
	{	/* recursive tuple definition, one or more elements */ \
public: \
	typedef _This _This_type; \
	typedef tuple<_This _EX(C) LIST(_TYPEX), PADDING_LIST(_NIL_PAD)> _Myt; \
	typedef tuple<LIST(_TYPEX) _EX(C) PADDING_LIST(_NIL_PAD)> _Mybase; \
	static const size_t _Mysize = _Sizeof<_This _EX(C) LIST(_TYPEX)>::value; \
_TUPLE_NONRVALUE(TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
_TUPLE_RVALUE(TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
_TUPLE_VARIADICS(TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	_Tuple_val<_This> _Myfirst;	/* the stored element */ \
	};

 #if _HAS_RVALUE_REFERENCES

 #if 0 < __GNUC__	/* compiler test */
#define _TUPLE_MOVE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	tuple(_Myt&& _Right) \
		: _Mybase(_STD forward<_Mybase>(_Right._Get_rest())), \
			_Myfirst(_STD forward<_This>(_Right._Myfirst._Val)) \
		{	/* construct by moving */ \
		}

 #else /* 0 < __GNUC__ */

 #if _HAS_FUNCTION_DELETE
#define _TUPLE_MOVE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	tuple(_Myt&& _Right) = default;

 #else /* _HAS_FUNCTION_DELETE */
#define _TUPLE_MOVE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	tuple(_Myt&& _Right) \
		: _Mybase(_STD forward<_Mybase>(_Right._Get_rest())), \
			_Myfirst(_STD forward<_This>(_Right._Myfirst._Val)) \
		{	/* construct by moving */ \
		}
 #endif /* _HAS_FUNCTION_DELETE */

 #endif /* 0 < __GNUC__ */

#define _TUPLE_RVALUE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	_TUPLE_MOVE( \
		TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	_Myt& operator=(_Myt&& _Right) \
		_NOEXCEPT_OP(is_nothrow_move_assignable<_This>::value \
			&& is_nothrow_move_assignable<_Mybase>::value) \
		{	/* assign by moving */ \
		_Myfirst = _STD forward<_This>(_Right._Myfirst._Val); \
		(_Mybase&)*this = _STD forward<_Mybase>(_Right._Get_rest()); \
		return (*this); \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		tuple(tuple<_Xarg0 _EX(C) LIST(_TYPE)>&& _Right, \
			typename _Tuple_enable< \
				tuple<_Xarg0 _EX(C) LIST(_TYPE)>, _Myt>::type = 0) \
		: _Mybase(_STD forward<typename tuple<_Xarg0 \
			_EX(C) LIST(_TYPE)>::_Mybase>( \
				_Right._Get_rest())), \
			_Myfirst(_STD forward<_Xarg0>(_Right._Myfirst._Val)) \
		{	/* construct by moving same size tuple */ \
		} \
	template<class _Alloc> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			_Myt&& _Right) \
		: _Mybase(allocator_arg, _Al, \
				_STD forward<_Mybase>(_Right._Get_rest())), \
			_Myfirst(_Al, _Tuple_alloc, \
				_STD forward<_This>(_Right._Myfirst._Val)) \
		{	/* construct by moving, allocator */ \
		} \
	template<class _First, \
		class _Second> \
		tuple(pair<_First, _Second>&& _Right, \
			typename _Tuple_enable< \
				tuple<_First, _Second>, _Myt>::type = 0) \
		: _Mybase(tuple<_Second>(_STD forward<_Second>(_Right.second))), \
			_Myfirst(_STD forward<_First>(_Right.first)) \
		{	/* construct by moving pair */ \
		/* no static_assert necessary */ \
		} \
	template<class _Alloc, \
		class _First, \
		class _Second> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			pair<_First, _Second>&& _Right, \
			typename _Tuple_enable< \
				tuple<_First, _Second>, _Myt>::type = 0) \
		: _Mybase(allocator_arg, _Al, \
				tuple<_Second>(_STD forward<_Second>(_Right.second))), \
			_Myfirst(_Al, _Tuple_alloc, \
				_STD forward<_First>(_Right.first)) \
		{	/* construct by moving pair, allocator */ \
		/* no static_assert necessary */ \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		_Myt& operator=(tuple<_Xarg0 _EX(C) LIST(_TYPE)>&& _Right) \
		{	/* assign by moving same size tuple */ \
		_Myfirst._Val = _STD forward<_Xarg0>(_Right._Myfirst._Val); \
		(_Mybase&)*this = \
			_STD forward<typename tuple<_Xarg0 \
				_EX(C) LIST(_TYPE)>::_Mybase>( \
					_Right._Get_rest()); \
		return (*this); \
		} \
	template<class _First, \
		class _Second> \
		_Myt& operator=(pair<_First, _Second>&& _Right) \
		{	/* assign by moving pair */ \
		_STATIC_ASSERT2(_Mysize == 2, \
			"assigning to tuple from object with different size"); \
		_Myfirst._Val = _STD forward<_First>(_Right.first); \
		(_Mybase&)*this = \
			tuple<_Second>(_STD forward<_Second>(_Right.second)); \
		return (*this); \
		}

 #else /* _HAS_RVALUE_REFERENCES */
 #define _TUPLE_RVALUE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4)
 #endif /* _HAS_RVALUE_REFERENCES */

 #if _HAS_FUNCTION_DELETE
#define _TUPLE_COPY( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	tuple(const _Myt& _Right) = default;

 #else /* _HAS_FUNCTION_DELETE */
#define _TUPLE_COPY( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	tuple(const _Myt& _Right) \
		: _Mybase(_Right._Get_rest()), \
			_Myfirst(_Right._Myfirst._Val) \
		{	/* construct by copying */ \
		}
 #endif /* _HAS_FUNCTION_DELETE */

#define _TUPLE_NONRVALUE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	tuple() \
		: _Mybase(), \
			_Myfirst() \
		{	/* construct default */ \
		} \
	template<class _Alloc> \
		tuple(allocator_arg_t, const _Alloc& _Al) \
		: _Mybase(allocator_arg, _Al), \
			_Myfirst(_Al, _Tuple_alloc) \
		{	/* construct default, allocator */ \
		} \
	_TUPLE_COPY( \
		TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<class _Alloc> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			const _Myt& _Right) \
		: _Mybase(allocator_arg, _Al, _Right._Get_rest()), \
			_Myfirst(_Al, _Tuple_alloc, \
				_Right._Myfirst._Val) \
		{	/* construct by copying, allocator */ \
		} \
	template<class _First, \
		class _Second> \
		tuple(const pair<_First, _Second>& _Right, \
			typename _Tuple_enable< \
				tuple<const _First&, const _Second&>, _Myt>::type = 0) \
		: _Mybase(tuple<_Second>(_Right.second)), \
			_Myfirst(_Right.first) \
		{	/* construct by copying pair */ \
		/* no static_assert necessary */ \
		} \
	template<class _Alloc, \
		class _First, \
		class _Second> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			const pair<_First, _Second>& _Right, \
			typename _Tuple_enable< \
				tuple<const _First&, const _Second&>, _Myt>::type = 0) \
		: _Mybase(allocator_arg, _Al, tuple<_Second>(_Right.second)), \
			_Myfirst(_Al, _Tuple_alloc, \
				_Right.first) \
		{	/* construct by copying pair, allocator */ \
		/* no static_assert necessary */ \
		} \
	_Myt& operator=(const _Myt& _Right) \
		{	/* assign */ \
		_Myfirst._Val = _Right._Myfirst._Val; \
		(_Mybase&)*this = _Right._Get_rest(); \
		return (*this); \
		} \
	template<class _First, \
		class _Second> \
		_Myt& operator=(const pair<_First, _Second>& _Right) \
		{	/* assign by copying pair */ \
		_STATIC_ASSERT2(_Mysize == 2, \
			"assigning to tuple from object with different size"); \
		_Myfirst._Val = _Right.first; \
		(_Mybase&)*this = tuple<_Second>(_Right.second); \
		return (*this); \
		} \
	_Mybase& _Get_rest() \
		{	/* get reference to rest of elements */ \
		return (*this); \
		} \
	const _Mybase& _Get_rest() const \
		{	/* get const reference to rest of elements */ \
		return (*this); \
		} \
	void swap(tuple& _Right) \
		_NOEXCEPT_OP( \
			_NOEXCEPT_OP(_Swap_adl(this->_Myfirst._Val, \
				_Right._Myfirst._Val)) \
			&& _NOEXCEPT_OP(_Swap_adl((_Mybase&)_Right, (_Mybase&)_Right))) \
		{	/* swap *this and _Right */ \
		_Swap_adl(_Myfirst._Val, _Right._Myfirst._Val); \
		_Mybase::swap((_Mybase&)_Right); \
		}

#define _TUPLE_VARIADICS( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	TEMPLATE_LIST(_CLASS_TYPE) \
		explicit tuple(_Tuple_alloc_t _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Mybase(LIST(_FORWARD_ARG)), \
			_Myfirst(allocator_arg) \
		{	/* construct smuggled allocator_arg_t element */ \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		tuple(const tuple<_Xarg0 _EX(C) LIST(_TYPE)>& _Right, \
			typename _Tuple_enable< \
				tuple<const _Xarg0& _EX(C) \
					LIST(_CONST_TYPE_REF)>, _Myt>::type = 0) \
		: _Mybase(_Right._Get_rest()), _Myfirst(_Right._Myfirst._Val) \
		{	/* construct by copying same size tuple */ \
		} \
	template<class _Alloc, \
		class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			const tuple<_Xarg0 _EX(C) LIST(_TYPE)>& _Right, \
			typename _Tuple_enable< \
				tuple<const _Xarg0& _EX(C) \
					LIST(_CONST_TYPE_REF)>, _Myt>::type = 0) \
		: _Mybase(allocator_arg, _Al, _Right._Get_rest()), \
			_Myfirst(_Al, _Tuple_alloc, \
				_Right._Myfirst._Val) \
		{	/* construct by copying same size tuple, allocator */ \
		} \
	explicit tuple(const _This& _Arg0 _EX(C) LIST(_CONST_TYPEX_REF_ARG)) \
		: _Mybase(LIST(_ARGX)), \
			_Myfirst(_Arg0) \
		{	/* construct from one or more copied elements */ \
		} \
	template<class _Alloc> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			const _This& _Arg0 _EX(C) LIST(_CONST_TYPEX_REF_ARG)) \
		: _Mybase(allocator_arg, _Al _EX(C) LIST(_ARGX)), \
			_Myfirst(_Al, _Tuple_alloc, _Arg0) \
		{	/* construct from one or more copied elements, allocator */ \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		explicit tuple(_Xarg0 _REFREF _Arg0 _EX(C) LIST(_TYPE_REFREF_ARG), \
			typename _Tuple_enable< \
				tuple<_Xarg0 _EX(C) \
					LIST(_TYPE)>, _Myt>::type = 0) \
		: _Mybase(LIST(_FORWARD_ARG)), \
			_Myfirst(_STD forward<_Xarg0>(_Arg0)) \
		{	/* construct from one or more moved elements */ \
		} \
	template<class _Alloc, \
		class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		tuple(allocator_arg_t, const _Alloc& _Al, \
			_Xarg0 _REFREF _Arg0 _EX(C) LIST(_TYPE_REFREF_ARG), \
			typename _Tuple_enable< \
				tuple<_Xarg0 _EX(C) \
					LIST(_TYPE)>, _Myt>::type = 0) \
		: _Mybase(allocator_arg, _Al _EX(C) LIST(_FORWARD_ARG)), \
			_Myfirst(_Al, _Tuple_alloc, \
				_STD forward<_Xarg0>(_Arg0)) \
		{	/* construct from one or more moved elements, allocator */ \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		_Myt& operator=(const tuple<_Xarg0 _EX(C) LIST(_TYPE)>& _Right) \
		{	/* assign by copying same size tuple */ \
		_Myfirst._Val = _Right._Myfirst._Val; \
		(_Mybase&)*this = _Right._Get_rest(); \
		return (*this); \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		bool _Equals(const tuple<_Xarg0 _EX(C) LIST(_TYPE)>& _Right) const \
		{	/* test if *this == _Right */ \
		return (_Myfirst._Val == _Right._Myfirst._Val \
			&& _Mybase::_Equals(_Right._Get_rest())); \
		} \
	template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
		bool _Less(const tuple<_Xarg0 _EX(C) LIST(_TYPE)>& _Right) const \
		{	/* test if *this < _Right */ \
		return (_Myfirst._Val < _Right._Myfirst._Val \
			|| !(_Right._Myfirst._Val < _Myfirst._Val) \
				&& _Mybase::_Less(_Right._Get_rest())); \
		}

_VARIADIC_EXPAND_0X(_CLASS_TUPLE, , , , )
#undef _TUPLE_COPY
#undef _TUPLE_MOVE
#undef _TUPLE_NONRVALUE
#undef _TUPLE_RVALUE
#undef _TUPLE_VARIADICS
#undef _CLASS_TUPLE
 #endif /* _HAS_VARIADIC_TEMPLATES */

	// OPERATORS FOR tuple

 #if _HAS_VARIADIC_TEMPLATES
template<class... _Types1,
	class... _Types2> inline
	_CONST_FUN bool operator==(const tuple<_Types1...>& _Left,
		const tuple<_Types2...>& _Right)
	{	// test if _Left == _Right
	return (_Left._Equals(_Right));
	}

template<class... _Types1,
	class... _Types2> inline
	_CONST_FUN bool operator!=(const tuple<_Types1...>& _Left,
		const tuple<_Types2...>& _Right)
	{	// test if _Left != _Right
	return (!(_Left == _Right));
	}

template<class... _Types1,
	class... _Types2> inline
	_CONST_FUN bool operator<(const tuple<_Types1...>& _Left,
		const tuple<_Types2...>& _Right)
	{	// test if _Left < _Right
	return (_Left._Less(_Right));
	}

template<class... _Types1,
	class... _Types2> inline
	_CONST_FUN bool operator>=(const tuple<_Types1...>& _Left,
		const tuple<_Types2...>& _Right)
	{	// test if _Left >= _Right
	return (!(_Left < _Right));
	}

template<class... _Types1,
	class... _Types2> inline
	_CONST_FUN bool operator>(const tuple<_Types1...>& _Left,
		const tuple<_Types2...>& _Right)
	{	// test if _Left > _Right
	return (_Right < _Left);
	}

template<class... _Types1,
	class... _Types2> inline
	_CONST_FUN bool operator<=(const tuple<_Types1...>& _Left,
		const tuple<_Types2...>& _Right)
	{	// test if _Left <= _Right
	return (!(_Right < _Left));
	}

template<class... _Types> inline
	void swap(tuple<_Types...>& _Left,
		tuple<_Types...>& _Right)
			_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
	{	// swap _Left and _Right
	return (_Left.swap(_Right));
	}

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _TUPLE_COMPARE_SWAP( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
TEMPLATE_LIST(_CLASS_TYPE_TYPEX) inline \
	bool operator==(const tuple<LIST(_TYPE)>& _Left, \
		const tuple<LIST(_TYPEX)>& _Right) \
	{	/* test if _Left == _Right */ \
	return (_Left._Equals(_Right)); \
	} \
TEMPLATE_LIST(_CLASS_TYPE_TYPEX) inline \
	bool operator!=(const tuple<LIST(_TYPE)>& _Left, \
		const tuple<LIST(_TYPEX)>& _Right) \
	{	/* test if _Left != _Right */ \
	return (!(_Left == _Right)); \
	} \
TEMPLATE_LIST(_CLASS_TYPE_TYPEX) inline \
	bool operator<(const tuple<LIST(_TYPE)>& _Left, \
		const tuple<LIST(_TYPEX)>& _Right) \
	{	/* test if _Left < _Right */ \
	return (_Left._Less(_Right)); \
	} \
TEMPLATE_LIST(_CLASS_TYPE_TYPEX) inline \
	bool operator>=(const tuple<LIST(_TYPE)>& _Left, \
		const tuple<LIST(_TYPEX)>& _Right) \
	{	/* test if _Left >= _Right */ \
	return (!(_Left < _Right)); \
	} \
TEMPLATE_LIST(_CLASS_TYPE_TYPEX) inline \
	bool operator>(const tuple<LIST(_TYPE)>& _Left, \
		const tuple<LIST(_TYPEX)>& _Right) \
	{	/* test if _Left > _Right */ \
	return (_Right < _Left); \
	} \
TEMPLATE_LIST(_CLASS_TYPE_TYPEX) inline \
	bool operator<=(const tuple<LIST(_TYPE)>& _Left, \
		const tuple<LIST(_TYPEX)>& _Right) \
	{	/* test if _Left <= _Right */ \
	return (!(_Right < _Left)); \
	} \
TEMPLATE_LIST(_CLASS_TYPE) inline \
	void swap(tuple<LIST(_TYPE)>& _Left, \
		tuple<LIST(_TYPE)>& _Right) \
			_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right))) \
	{	/* swap _Left and _Right */ \
	return (_Left.swap(_Right)); \
	}

_VARIADIC_EXPAND_0X(_TUPLE_COMPARE_SWAP, , , , )
#undef _TUPLE_COMPARE_SWAP
 #endif /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_VARIADIC_TEMPLATES
	// CLASS _Tuple_element (find element by type)
template<class _Ty,
	class _Tuple>
	struct _Tuple_element;

template<class _This,
	class... _Rest>
	struct _Tuple_element<_This, tuple<_This, _Rest...> >
	{	// select first element
	typedef int _Check_type;
	_STATIC_ASSERT2((is_void<typename _Tuple_element<_This,
		tuple<_Rest...> >::_Check_type>::value),
		"duplicate type T in get<T>(tuple)");

	typedef _This type;
	typedef tuple<_This, _Rest...> _Ttype;
	};

template<class _Ty,
	class _This,
	class... _Rest>
	struct _Tuple_element<_Ty, tuple<_This, _Rest...> >
		: public _Tuple_element<_Ty, tuple<_Rest...> >
	{	// recursive _Tuple_element definition
	};

template<class _Ty>
	struct _Tuple_element<_Ty, tuple<> >
	{	// backstop _Tuple_element definition
	typedef void _Check_type;	// proof that no duplicate type exists
	};

template<class _Ty,
	class _Tuple>
	struct _Tuple_element<_Ty, const _Tuple>
		: public _Tuple_element<_Ty, _Tuple>
	{	// _Tuple_element for const
	typedef _Tuple_element<_Ty, _Tuple> _Mybase;
	typedef typename add_const<typename _Mybase::type>::type type;
	};

template<class _Ty,
	class _Tuple>
	struct _Tuple_element<_Ty, volatile _Tuple>
		: public _Tuple_element<_Ty, _Tuple>
	{	// _Tuple_element for volatile
	typedef _Tuple_element<_Ty, _Tuple> _Mybase;
	typedef typename add_volatile<typename _Mybase::type>::type type;
	};

template<class _Ty,
	class _Tuple>
	struct _Tuple_element<_Ty, const volatile _Tuple>
		: public _Tuple_element<_Ty, _Tuple>
	{	// _Tuple_element for const volatile
	typedef _Tuple_element<_Ty, _Tuple> _Mybase;
	typedef typename add_cv<typename _Mybase::type>::type type;
	};

	// TEMPLATE FUNCTION get (by index)
template<size_t _Index,
	class... _Types> inline
	_CONST_FUN typename tuple_element<_Index, tuple<_Types...> >::type&
		get(tuple<_Types...>& _Tuple) _NOEXCEPT
	{	// get reference to _Index element of tuple
	typedef typename tuple_element<_Index, tuple<_Types...> >::_Ttype
		_Ttype;
	return (((_Ttype&)_Tuple)._Myfirst._Val);
	}

template<size_t _Index,
	class... _Types> inline
	_CONST_FUN const typename tuple_element<_Index, tuple<_Types...> >::type&
		get(const tuple<_Types...>& _Tuple) _NOEXCEPT
	{	// get const reference to _Index element of tuple
	typedef typename tuple_element<_Index, tuple<_Types...> >::_Ttype
		_Ttype;
	return (((_Ttype&)_Tuple)._Myfirst._Val);
	}

template<size_t _Index,
	class... _Types> inline
	_CONST_FUN typename tuple_element<_Index, tuple<_Types...> >::type&&
		get(tuple<_Types...>&& _Tuple) _NOEXCEPT
	{	// get rvalue reference to _Index element of tuple
	typedef typename tuple_element<_Index, tuple<_Types...> >::_Ttype
		_Ttype;
	typedef typename tuple_element<_Index, tuple<_Types...> >::type&&
		_RRtype;
	return (_STD forward<_RRtype>(((_Ttype&)_Tuple)._Myfirst._Val));
	}

	// TEMPLATE FUNCTION get (by type)
template<class _Ty,
	class... _Types> inline
	_CONST_FUN _Ty& get(tuple<_Types...>& _Tuple) _NOEXCEPT
	{	// get reference to _Ty element of tuple
	typedef typename _Tuple_element<_Ty, tuple<_Types...> >::_Ttype _Ttype;
	return (((_Ttype&)_Tuple)._Myfirst._Val);
	}

template<class _Ty,
	class... _Types> inline
	_CONST_FUN const _Ty& get(const tuple<_Types...>& _Tuple) _NOEXCEPT
	{	// get const reference to _Ty element of tuple
	typedef typename _Tuple_element<_Ty, tuple<_Types...> >::_Ttype _Ttype;
	return (((_Ttype&)_Tuple)._Myfirst._Val);
	}

template<class _Ty,
	class... _Types> inline
	_CONST_FUN _Ty&& get(tuple<_Types...>&& _Tuple) _NOEXCEPT
	{	// get rvalue reference to _Ty element of tuple
	typedef typename _Tuple_element<_Ty, tuple<_Types...> >::_Ttype _Ttype;
	return (_STD forward<_Ty&&>(((_Ttype&)_Tuple)._Myfirst._Val));
	}

	// TEMPLATE FUNCTION make_tuple
template<class... _Types> inline
	_CONST_FUN tuple<typename _Unrefwrap<_Types>::type...>
		make_tuple(_Types&&... _Args)
	{	// make tuple from elements
	typedef tuple<typename _Unrefwrap<_Types>::type...> _Ttype;
	return (_Ttype(_STD forward<_Types>(_Args)...));
	}

	// TEMPLATE FUNCTION tie
template<class... _Types> inline
	_CONST_FUN tuple<_Types&...>
		tie(_Types&... _Args) _NOEXCEPT
	{	// make tuple from elements
	typedef tuple<_Types&...> _Ttype;
	return (_Ttype(_Args...));
	}

 #else /* _HAS_VARIADIC_TEMPLATES */
	// FUNCTION get
#define _TUPLE_GET( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<size_t _Index _EX(C) LIST(_CLASS_TYPE)> inline \
	typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_Rtype \
		get(tuple<LIST(_TYPE)>& _Tuple) \
	{	/* get reference to _Index element of tuple */ \
	typedef typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_Ttype \
		_Ttype; \
	return (((_Ttype&)_Tuple)._Myfirst._Val); \
	} \
template<size_t _Index _EX(C) LIST(_CLASS_TYPE)> inline \
	typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_Ctype \
		get(const tuple<LIST(_TYPE)>& _Tuple) \
	{	/* get const reference to _Index element of tuple */ \
	typedef typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_Ttype \
		_Ttype; \
	return (((_Ttype&)_Tuple)._Myfirst._Val); \
	}

_VARIADIC_EXPAND_0X(_TUPLE_GET, _Comma, , , )
#undef _TUPLE_GET

 #if _HAS_RVALUE_REFERENCES
#define _TUPLE_GET_RVALUE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<size_t _Index _EX(C) LIST(_CLASS_TYPE)> inline \
	typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_RRtype \
		get(tuple<LIST(_TYPE)>&& _Tuple) \
	{	/* get rvalue reference to _Index element of tuple */ \
	typedef typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_RRtype \
		_RRtype; \
	typedef typename tuple_element<_Index, tuple<LIST(_TYPE)> >::_Ttype \
		_Ttype; \
	return (_STD forward<_RRtype>(((_Ttype&)_Tuple)._Myfirst._Val)); \
	}

_VARIADIC_EXPAND_0X(_TUPLE_GET_RVALUE, _Comma, , , )
#undef _TUPLE_GET_RVALUE
 #endif /* _HAS_RVALUE_REFERENCES */

	// TEMPLATE FUNCTION make_tuple
#define _MAKE_TUPLE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
TEMPLATE_LIST(_CLASS_TYPE) inline \
	tuple<LIST(_UNREFWRAP_TYPE)> \
		make_tuple(LIST(_TYPE_REFREF_ARG)) \
	{	/* make tuple from elements */ \
	typedef tuple<LIST(_UNREFWRAP_TYPE)> _Ttype; \
	return (_Ttype(LIST(_FORWARD_ARG))); \
	}

_VARIADIC_EXPAND_0X(_MAKE_TUPLE, , , , )
#undef _MAKE_TUPLE

	// TEMPLATE FUNCTION tie
#define _TUPLE_TIE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
TEMPLATE_LIST(_CLASS_TYPE) inline \
	tuple<LIST(_TYPE_REF)> \
		tie(LIST(_TYPE_REF_ARG)) _NOEXCEPT \
	{	/* make tuple from elements */ \
	typedef tuple<LIST(_TYPE_REF)> _Ttype; \
	return (_Ttype(LIST(_ARG))); \
	}

_VARIADIC_EXPAND_0X(_TUPLE_TIE, , , , )
#undef _TUPLE_TIE
 #endif /* _HAS_VARIADIC_TEMPLATES */

	// TEMPLATE FUNCTION forward_as_tuple

 #if _HAS_VARIADIC_TEMPLATES
template<class... _Types> inline
	_CONST_FUN tuple<_Types&&...>
		forward_as_tuple(_Types&&... _Args) _NOEXCEPT
	{	// forward arguments in a tuple
	return (tuple<_Types&&...>(_STD forward<_Types>(_Args)...));
	}

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _FORWARD_AS_TUPLE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	TEMPLATE_LIST(_CLASS_TYPE) inline \
	tuple<LIST(_TYPE_REFREF)> \
		forward_as_tuple(LIST(_TYPE_REFREF_ARG)) _NOEXCEPT\
	{	/* forward arguments in a tuple */ \
	return (tuple<LIST(_TYPE_REFREF)>(LIST(_FORWARD_ARG))); \
	}

_VARIADIC_EXPAND_0X(_FORWARD_AS_TUPLE, , , , )
#undef _FORWARD_AS_TUPLE
 #endif /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_VARIADIC_TEMPLATES
	// TEMPLATE STRUCT _Cat_sequences
template<class _Seq_type1,
	class _Seq_type2>
	struct _Cat_sequences;

template<size_t... _Indexes1,
	size_t... _Indexes2>
	struct _Cat_sequences<integer_sequence<size_t, _Indexes1...>,
		integer_sequence<size_t, _Indexes2...> >
	{	// concatenates two integer_sequence types
	typedef integer_sequence<size_t, _Indexes1..., _Indexes2...> type;
	};

	// FORWARD DECLARATIONS
template<class _Ty,
	_INT_OR_SIZE_T _Size>
	class array;

template<size_t _Idx,
	class _Ty,
	_INT_OR_SIZE_T _Size>
	_CONST_FUN _Ty& get(array<_Ty, _Size>& _Arr) _NOEXCEPT;

template<size_t _Idx,
	class _Ty,
	_INT_OR_SIZE_T _Size>
	_CONST_FUN const _Ty& get(const array<_Ty, _Size>& _Arr) _NOEXCEPT;

template<size_t _Idx,
	class _Ty,
	_INT_OR_SIZE_T _Size>
	_CONST_FUN _Ty&& get(array<_Ty, _Size>&& _Arr) _NOEXCEPT;

	// TEMPLATE STRUCT _View_as_tuple
template<class _Ty,
	class... _For_array>
	struct _View_as_tuple
	{	// tuple_cat() supports only tuples, pairs, and arrays
	_STATIC_ASSERT2(_Always_false<_Ty>::value,
		"Unsupported tuple_cat arguments.");
	};

template<class... _Types>
	struct _View_as_tuple<tuple<_Types...> >
	{	// view a tuple as a tuple
	typedef tuple<_Types...> type;
	};

template<class _Ty1,
	class _Ty2>
	struct _View_as_tuple<pair<_Ty1, _Ty2> >
	{	// view a pair as a tuple
	typedef tuple<_Ty1, _Ty2> type;
	};

template<class _Ty,
	class... _Types>
	struct _View_as_tuple<array<_Ty, 0>, _Types...>
	{	// view an array as a tuple; ends recursion at 0
	typedef tuple<_Types...> type;
	};

template<class _Ty,
	_INT_OR_SIZE_T _Size,
	class... _Types>
	struct _View_as_tuple<array<_Ty, _Size>, _Types...>
		: _View_as_tuple<array<_Ty, _Size - 1>, _Ty, _Types...>
	{	// view an array as a tuple; counts down to 0
	};

	// TEMPLATE STRUCT _Repeat_for
template<size_t _Nx,
	class _Ty>
	struct _Repeat_for
		: integral_constant<size_t, _Nx>
	{	// repeats _Nx for each _Ty in a parameter pack
	};

	// TEMPLATE FUNCTION tuple_cat
template<class _Ret,
	class _Kx_arg,
	class _Ix_arg,
	size_t _Ix_next,
	class... _Tuples>
	struct _Tuple_cat2
	{	// determine tuple_cat's return type and _Kx/_Ix indices
	_STATIC_ASSERT2(sizeof...(_Tuples) == 0,
		"Unsupported tuple_cat arguments.");
	typedef _Ret type;
	typedef _Kx_arg _Kx_arg_seq;
	typedef _Ix_arg _Ix_arg_seq;
	};

template<class... _Types1,
	class _Kx_arg,
	size_t... _Ix,
	size_t _Ix_next,
	class... _Types2,
	class... _Rest>
	struct _Tuple_cat2<tuple<_Types1...>, _Kx_arg,
		integer_sequence<size_t, _Ix...>, _Ix_next,
		tuple<_Types2...>, _Rest...>
		: _Tuple_cat2<
			tuple<_Types1..., _Types2...>,
			typename _Cat_sequences<_Kx_arg,
				typename make_integer_sequence<size_t, sizeof...(_Types2)>
					::type>::type,
			integer_sequence<size_t, _Ix...,
				_Repeat_for<_Ix_next, _Types2>::value...>,
			_Ix_next + 1,
			_Rest...>
	{	// determine tuple_cat's return type and _Kx/_Ix indices
	};

template<class... _Tuples>
	struct _Tuple_cat1
		: _Tuple_cat2<tuple<>, integer_sequence<size_t>,
				integer_sequence<size_t>, 0,
			typename _View_as_tuple<typename decay<_Tuples>::type>::type...>
	{	// prepare to determine tuple_cat's return type and _Kx/_Ix indices
	};

template<class _Ret,
	size_t... _Kx,
	size_t... _Ix,
	class _Ty> inline
	_CONST_FUN _Ret _Tuple_cat(integer_sequence<size_t, _Kx...>,
		integer_sequence<size_t, _Ix...>, _Ty&& _Arg)
	{	// concatenate tuples
	return (_Ret(_STD get<_Kx>(_STD get<_Ix>(_STD forward<_Ty>(_Arg)))...));
	}

template<class... _Tuples> inline
	_CONST_FUN typename _Tuple_cat1<_Tuples...>::type
		tuple_cat(_Tuples&&... _Tpls)
	{	// concatenate tuples
	typedef _Tuple_cat1<_Tuples...> _Cat1;
	return (_Tuple_cat<typename _Cat1::type>(
		typename _Cat1::_Kx_arg_seq(), typename _Cat1::_Ix_arg_seq(),
		_STD forward_as_tuple(_STD forward<_Tuples>(_Tpls)...)));
	}

 #else /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_CPP0X
	// FUNCTION tuple_cat
#define _TUPLE_CAT_X0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	TEMPLATE_LIST(_CLASS_TYPE) inline \
		tuple<LIST(_TYPE)> tuple_cat( \
			tuple<LIST(_TYPE)>&& _Tpl1, \
			tuple<>) \
	{	/* concatenate (possibly empty) tuple to empty tuple */ \
	return (_STD forward<tuple<LIST(_TYPE)> >(_Tpl1)); \
	} \
	TEMPLATE_LIST(_CLASS_TYPE) inline \
		tuple<LIST(_TYPE)> tuple_cat( \
			const tuple<LIST(_TYPE)>& _Tpl1, \
			tuple<>) \
	{	/* concatenate (possibly empty) tuple to empty tuple */ \
	return (_Tpl1); \
	}

_VARIADIC_EXPAND_0X(_TUPLE_CAT_X0, , , , )
#undef _TUPLE_CAT_X0

#define _TUPLE_CAT_0X( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	TEMPLATE_LIST(_CLASS_TYPE) inline \
		tuple<LIST(_TYPE)> tuple_cat( \
			tuple<>, \
			tuple<LIST(_TYPE)>&& _Tpl1) \
	{	/* concatenate empty tuple to non-empty tuple */ \
	return (_STD forward<tuple<LIST(_TYPE)> >(_Tpl1)); \
	} \
	TEMPLATE_LIST(_CLASS_TYPE) inline \
		tuple<LIST(_TYPE)> tuple_cat( \
			tuple<>, \
			const tuple<LIST(_TYPE)>& _Tpl1) \
	{	/* concatenate empty tuple to non-empty tuple */ \
	return (_Tpl1); \
	}

_VARIADIC_EXPAND_1X(_TUPLE_CAT_0X, , , , )
#undef _TUPLE_CAT_0X

#define _TUPLE_CAT( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
	template<LIST1(_CLASS_TYPE) _EX(C2) LIST2(_CLASS_TYPEX)> inline \
		tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)> \
			tuple_cat(tuple<LIST1(_TYPE)>&& _Tpl1, \
				tuple<LIST2(_TYPEX)>&& _Tpl2) \
	{	/* concatenate nonempty tuple with tuple */ \
	return (tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)>( \
		LIST1(_FORWARD_ELEMENT_ARG) \
		_EX(C2) LIST2(_FORWARD_ELEMENT_ARGX))); \
	} \
	template<LIST1(_CLASS_TYPE) _EX(C2) LIST2(_CLASS_TYPEX)> \
		tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)> \
			tuple_cat(const tuple<LIST1(_TYPE)>& _Tpl1, \
				tuple<LIST2(_TYPEX)>&& _Tpl2) \
	{	/* concatenate nonempty tuple with tuple */ \
	return (tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)>( \
		LIST1(_ELEMENT_ARG) \
		_EX(C2) LIST2(_FORWARD_ELEMENT_ARGX))); \
	} \
	template<LIST1(_CLASS_TYPE) _EX(C2) LIST2(_CLASS_TYPEX)> \
		tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)> \
			tuple_cat(tuple<LIST1(_TYPE)>&& _Tpl1, \
				const tuple<LIST2(_TYPEX)>& _Tpl2) \
	{	/* concatenate nonempty tuple with tuple */ \
	return (tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)>( \
		LIST1(_FORWARD_ELEMENT_ARG) \
		_EX(C2) LIST2(_ELEMENT_ARGX))); \
	} \
	template<LIST1(_CLASS_TYPE) _EX(C2) LIST2(_CLASS_TYPEX)> \
		tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)> \
			tuple_cat(const tuple<LIST1(_TYPE)>& _Tpl1, \
				const tuple<LIST2(_TYPEX)>& _Tpl2) \
	{	/* concatenate nonempty tuple with tuple */ \
	return (tuple<LIST1(_TYPE) _EX(C2) LIST2(_TYPEX)>( \
		LIST1(_ELEMENT_ARG) \
		_EX(C2) LIST2(_ELEMENT_ARGX))); \
	}

_VARIADIC_EXPAND_1X_1D(_TUPLE_CAT)
#undef _TUPLE_CAT

#define _TUPLE_CAT_XXX( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _Tuple1, \
	class _Tuple2, \
	class _Tuple3 _EX(C) LIST(_CLASS_TYPE)> \
	auto inline tuple_cat(_Tuple1&& _Tp1, _Tuple2&& _Tp2, _Tuple3&& _Tp3 \
		_EX(C) LIST(_TYPE_REFREF_ARG)) \
		-> decltype(tuple_cat( \
		tuple_cat(_STD forward<_Tuple1>(_Tp1), \
			_STD forward<_Tuple2>(_Tp2)), \
		tuple_cat(_STD forward<_Tuple3>(_Tp3) \
			_EX(C) LIST(_FORWARD_ARG)))) \
	{	/* concatenate three or more tuples */ \
	return (tuple_cat( \
		tuple_cat(_STD forward<_Tuple1>(_Tp1), \
			_STD forward<_Tuple2>(_Tp2)), \
		tuple_cat(_STD forward<_Tuple3>(_Tp3) \
			_EX(C) LIST(_FORWARD_ARG)))); \
	} \
TEMPLATE_LIST(_CLASS_TYPE) \
inline tuple<LIST(_TYPE)> \
	tuple_cat(tuple<LIST(_TYPE)>&& _Tpl1) \
	{	/* concatenate single tuple */ \
	return (_STD forward<tuple<LIST(_TYPE)> >(_Tpl1)); \
	} \
TEMPLATE_LIST(_CLASS_TYPE) \
inline tuple<LIST(_TYPE)> \
	tuple_cat(const tuple<LIST(_TYPE)>& _Tpl1) \
	{	/* concatenate single tuple */ \
	return (_Tpl1); \
	}

_VARIADIC_EXPAND_0X(_TUPLE_CAT_XXX, , , , )
#undef _TUPLE_CAT_XXX

inline tuple<> tuple_cat()
	{	// concatenate no tuples
	return (tuple<>());
	}
 #endif /* _HAS_CPP0X */

 #endif /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_VARIADIC_TEMPLATES

 #if _HAS_DELEGATING_CONSTRUCTORS
	// TEMPLATE CONSTRUCTOR pair::pair(tuple, tuple, sequence, sequence)
template<class _Ty1,
	class _Ty2>
	template<class _Tuple1,
		class _Tuple2,
		size_t... _Indexes1,
		size_t... _Indexes2> inline
		pair<_Ty1, _Ty2>::pair(_Tuple1& _Val1,
			_Tuple2& _Val2,
			integer_sequence<size_t, _Indexes1...>,
			integer_sequence<size_t, _Indexes2...>)
		: first(_STD get<_Indexes1>(_STD move(_Val1))...),
			second(_STD get<_Indexes2>(_STD move(_Val2))...)
		{	// construct from pair of tuples
		}

	// TEMPLATE CONSTRUCTOR pair::pair(piecewise_construct_t, tuple, tuple)
template<class _Ty1,
	class _Ty2>
	template<class... _Types1,
		class... _Types2> inline
		pair<_Ty1, _Ty2>::pair(piecewise_construct_t,
			tuple<_Types1...> _Val1,
			tuple<_Types2...> _Val2)
		: pair(_Val1, _Val2,
			make_integer_sequence<size_t, sizeof...(_Types1)>(),
			make_integer_sequence<size_t, sizeof...(_Types2)>())
		{	// construct from pair of tuples
		}

 #else /* _HAS_DELEGATING_CONSTRUCTORS */
	// TEMPLATE HELPER pair::_Init(tuple, integer_sequence)
template<class _Ty1,
	class _Ty2>
	template<class _Ty,
		class _Tuple,
		size_t... _Indexes> inline
		typename remove_cv<_Ty>::type pair<_Ty1, _Ty2>::_Init(
			_Tuple& _Val, integer_sequence<size_t, _Indexes...>)
		{	// construct from a tuple
		typedef typename remove_cv<_Ty>::type _Myty;
		return (_Myty(_STD get<_Indexes>(_STD move(_Val))...));
		}

	// TEMPLATE CONSTRUCTOR pair::pair(piecewise_construct_t, tuple, tuple)
template<class _Ty1,
	class _Ty2>
	template<class... _Types1,
		class... _Types2> inline
		pair<_Ty1, _Ty2>::pair(piecewise_construct_t,
			tuple<_Types1...> _Val1,
			tuple<_Types2...> _Val2)
		: first(_STD move(_Init<first_type>(_Val1,
				make_integer_sequence<size_t, sizeof...(_Types1)>()))),
			second(_STD move(_Init<second_type>(_Val2,
				make_integer_sequence<size_t, sizeof...(_Types2)>())))
		{	// construct from pair of tuples
		}
 #endif /* _HAS_DELEGATING_CONSTRUCTORS */

 #else /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_RVALUE_REFERENCES
#define _PAIR_TUPLE_CONSTRUCTOR0( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
template<class _Ty1, \
	class _Ty2> \
	TEMPLATE_LIST1(_CLASS_TYPE) \
		pair<_Ty1, _Ty2>::pair(piecewise_construct_t, \
			tuple<LIST1(_TYPE)> _Tpl1, \
			tuple<>) \
			: first(LIST1(_FORWARD_ELEMENT_ARG)), \
				second() \
		{	/* construct from (tuple<0-X>, tuple<>) pair */ \
		}

_VARIADIC_EXPAND_0X_0(_PAIR_TUPLE_CONSTRUCTOR0)
#undef _PAIR_TUPLE_CONSTRUCTOR0

#define _PAIR_TUPLE_CONSTRUCTOR1( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
template<class _Ty1, \
	class _Ty2> \
	template<LIST2(_CLASS_TYPEX)> \
		pair<_Ty1, _Ty2>::pair(piecewise_construct_t, \
			tuple<>, \
			tuple<LIST2(_TYPEX)> _Tpl2) \
			: first(), \
				second(LIST2(_FORWARD_ELEMENT_ARGX)) \
		{	/* construct from (tuple<>, tuple<1-X>) pair */ \
		}

_VARIADIC_EXPAND_0_1X(_PAIR_TUPLE_CONSTRUCTOR1)
#undef _PAIR_TUPLE_CONSTRUCTOR1

#define _PAIR_TUPLE_CONSTRUCTOR2( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
template<class _Ty1, \
	class _Ty2> \
	template<LIST1(_CLASS_TYPE), LIST2(_CLASS_TYPEX)> \
		pair<_Ty1, _Ty2>::pair(piecewise_construct_t, \
			tuple<LIST1(_TYPE)> _Tpl1, \
			tuple<LIST2(_TYPEX)> _Tpl2) \
			: first(LIST1(_FORWARD_ELEMENT_ARG)), \
				second(LIST2(_FORWARD_ELEMENT_ARGX)) \
		{	/* construct from pair of tuples */ \
		}

_VARIADIC_EXPAND_1X_1X(_PAIR_TUPLE_CONSTRUCTOR2)
#undef _PAIR_TUPLE_CONSTRUCTOR2
 #endif /* _HAS_RVALUE_REFERENCES */

 #endif /* _HAS_VARIADIC_TEMPLATES */
_STD_END

namespace std {
 #if _HAS_VARIADIC_TEMPLATES
	// TEMPLATE STRUCT uses_allocator
template<class... _Types,
	class _Alloc>
	struct uses_allocator<tuple<_Types...>, _Alloc>
		: true_type
	{	// true_type if container allocator enabled
	};

 #else /* _HAS_VARIADIC_TEMPLATES */
template<class _Alloc>
	struct uses_allocator<tuple<>, _Alloc>
		: true_type
	{	// true_type if container allocator enabled
	};

#define _TUPLE_USES_ALLOCATOR( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE), \
	class _Alloc> \
	struct uses_allocator<tuple<_Xarg0 _EX(C) LIST(_TYPE)>, _Alloc> \
		: true_type \
	{	/* true_type if container allocator enabled */ \
	};

_VARIADIC_EXPAND_0X(_TUPLE_USES_ALLOCATOR, , , , )
#undef _TUPLE_USES_ALLOCATOR
 #endif /* _HAS_VARIADIC_TEMPLATES */
}	// namespace std

 #if _HAS_TR1_IMPORTS
_STD_BEGIN
namespace tr1 {	// TR1 ADDITIONS
using _STD get;
using _STD ignore;
using _STD make_tuple;
using _STD ref;
using _STD tie;
using _STD tuple;
}	// namespace tr1
_STD_END
 #endif /* _HAS_TR1_IMPORTS */

#endif /* _TUPLE_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:1422 */
